Skip to content

feat(sender): add 1080p capture profiles for non-Retina 1080p receivers - #168

Open
polmarinm wants to merge 3 commits into
swellweb:dev-3.4.0from
polmarinm:feat/1080p-capture-profile
Open

feat(sender): add 1080p capture profiles for non-Retina 1080p receivers#168
polmarinm wants to merge 3 commits into
swellweb:dev-3.4.0from
polmarinm:feat/1080p-capture-profile

Conversation

@polmarinm

Copy link
Copy Markdown

Why

Every 21.5-inch iMac that is not a Retina 4K model has a native 1920 × 1080 panel,
and the lowest stream profile today is 1440p. Those receivers therefore have to
downscale every frame, which costs decode headroom on exactly the machines that
have the least of it, and the desktop never lands on the panel at its true size.

Decode load in pixels per second, against the existing profiles:

Profile Pixels/s
smooth1440p60 (2560×1440×60) 221 Mpx/s
standard1440p (2560×1440×30) 110 Mpx/s
smooth1080p60 (1920×1080×60) 124 Mpx/s
standard1080p (1920×1080×30) 62 Mpx/s

Both new profiles sit at or below standard1440p, which is already the comfortable
setting on older receivers.

What changed

feat(sender): add 1080p capture profile — adds standard1080p (30 FPS,
20 Mbps) and smooth1080p60 (60 FPS, 30 Mbps), titled Full HD and Full HD 60.
Bit rates follow the existing bits-per-pixel scaling, and both keep H.264 with the
same opportunistic HEVC upgrade the other sub-4K profiles use. Aliases 1080p,
1080, fullhd, 1920x1080, 1080p60, fullhd60 and smooth1080 are wired
into --preset, with strings added to all five language files.

feat(display): render 1080p profiles at native 1x scale — the profile alone
is not enough to make the feature work, because the virtual display geometry does
not come from the capture profile.

The receiver advertises a fixed 5120x2880 panel with a 2560x1440 HiDPI mode and
"hiDPI":true regardless of the display it is attached to
(TargetBridge-Receiver/TBReceiverC/src/main.c). The sender takes those values as
the virtual display geometry, so a 1080p stream was captured from a 1440p HiDPI
desktop and rescaled twice on the way to a 1080p panel.

Render matching does not fix it either: it sizes the backing store to the stream
but keeps the strictly 2x HiDPI contract, so 1080p becomes a 960×540 desktop.
Capture is 1:1, but every control is drawn at 2x on a panel with no extra pixels to
resolve it.

So TBVirtualDisplayModeSize gains an explicit isHiDPI, defaulting to the
existing 2x behaviour, and the capture profile chooses. The 1080p profiles declare
native scale and get a 1920x1080 1x mode. Every other profile is untouched and
still derives its mode and HiDPI flag from the receiver profile.

The trigger is the profile rather than the receiver's reported panel size, because
that value is a compile-time constant on the receiver and cannot distinguish a
1080p panel from a 5K one. If you would rather the receiver reported its real panel
and the sender keyed off that, I am happy to rework it that way — it would be the
more general fix, but it needs a receiver change and a protocol story for older
receivers, so I kept this PR sender-only.

Testing

Sender: MacBook Pro, Apple Silicon, macOS 26.5.2, Xcode 26.6.
Receiver: iMac10,1 21.5-inch (Core 2 Duo E7600, GeForce 9400, 1920×1080 panel)
running macOS 11.7.10 via OpenCore Legacy Patcher, over a direct Ethernet link.

  • standard1080p runs stable and fluid, and the desktop now reaches the panel at
    its true size — verified with system_profiler SPDisplaysDataType showing the
    virtual display at 1920 × 1080 rather than the previous 2560 × 1440.
  • smooth1080p60 runs and is usable, though not as smooth as standard1080p on
    this particular receiver.
  • Unit tests added for the alias parsing and for the 1x/HiDPI backing-store maths.
    Full suite passes from a clean checkout.

Note, not part of this PR

On this receiver the session negotiates HEVC, because supportsHEVCDecode is
reported true, but a GeForce 9400 has no HEVC decoder and the work lands in
software. That affects standard1440p equally and is not introduced here, so I
have left it alone rather than widen this PR. Happy to open a separate issue.

polmarinm and others added 3 commits August 15, 2026 14:34
Add `standard1080p` (30 FPS) and `smooth1080p60` (60 FPS) so receivers with
a 1920x1080 panel decode at their native resolution instead of downscaling a
1440p stream. Every 21.5-inch non-Retina iMac has a 1080p panel, and those are
the machines with the least decode headroom to spare.

Decode load in pixels per second, against the existing profiles:

  smooth1440p60   2560x1440x60  221 Mpx/s
  standard1440p   2560x1440x30  110 Mpx/s
  smooth1080p60   1920x1080x60  124 Mpx/s
  standard1080p   1920x1080x30   62 Mpx/s

Both new profiles sit at or below `standard1440p`, which is already the
comfortable setting on older receivers.

Bit rates follow the existing bits-per-pixel scaling: 20 Mbps for the 30 FPS
profile and 30 Mbps for the 60 FPS one. Both keep H.264 with the same
opportunistic HEVC upgrade the other sub-4K profiles use, so receivers without
hardware HEVC decode are unaffected.

The profiles are listed first so the picker stays ordered by resolution, and
`renderMatchedDisplayMode` needs no special casing: it already derives the
HiDPI mode generically, giving 960x540 backed by a 1920x1080 framebuffer.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
List `standard1080p` and `smooth1080p60` alongside their aliases in the
automation reference and the `targetbridge` CLI header, and widen the stream
profile range quoted in the README.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The receiver advertises a fixed 5120x2880 panel with a 2560x1440 HiDPI mode and
`"hiDPI":true`, regardless of the display it is actually attached to. The sender
took those values as the virtual display geometry, so a 1080p stream was captured
from a 1440p HiDPI desktop and rescaled twice on the way to a 1080p panel: the
desktop arrived at the wrong size and paid for two non-integer resamples.

Render matching could not fix this either. It sizes the backing store to the
stream but keeps the strictly 2x HiDPI contract, so 1080p became a 960x540
desktop — capture is 1:1, but every control is drawn at 2x on a panel with no
extra pixels to resolve it.

Give `TBVirtualDisplayModeSize` an explicit `isHiDPI`, defaulting to the existing
2x behaviour, and let the capture profile choose. The 1080p profiles declare
native scale and get a 1920x1080 1x mode; every other profile is untouched and
still derives its mode and HiDPI flag from the receiver profile.

The trigger is the profile rather than the receiver's reported panel size,
because that value is a compile-time constant on the receiver and cannot
distinguish a 1080p panel from a 5K one.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant